import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
import numpy as np
import joblib
import matplotlib.pyplot as plt
import seaborn as sns

# 读取数据集
df = pd.read_csv('Match_data.csv')  # 根据实际情况读取数据

# 选择需要归一化的特征列
features = ['price', 'rank', 'previous', 'best', 'host']

# 创建MinMaxScaler对象
scaler = MinMaxScaler()

# 对特征进行归一化
df[features] = scaler.fit_transform(df[features])

# 保存MinMaxScaler对象，以便在预测时使用
joblib.dump(scaler, 'scaler.pkl')

# 选择特征列和目标变量
target = 'result'

# 分割数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(df[features], df[target], test_size=0.2, random_state=42)

# 创建SVR模型
svr_model = SVR(kernel='rbf', C=1.0, epsilon=0.1)

# 训练模型
svr_model.fit(X_train, y_train)

# 保存训练好的模型
joblib.dump(svr_model, 'svr_model.pkl')

# 预测测试集
y_pred = svr_model.predict(X_test)


# 定义一组指定的数字
specified_values = [5, 10, 20, 25, 30, 40, 50]

# 定义一个函数来找到最接近的指定数字
def find_nearest_value(value, specified_values):
    return min(specified_values, key=lambda x: abs(x - value))

# 应用函数到每个预测值
y_pred_adjusted = [find_nearest_value(pred, specified_values) for pred in y_pred]

# 评估调整后的模型性能
mse_adjusted = mean_squared_error(y_test, y_pred_adjusted)
rmse_adjusted = np.sqrt(mse_adjusted)  # 手动计算均方根误差
mae_adjusted = mean_absolute_error(y_test, y_pred_adjusted)
r2_adjusted = r2_score(y_test, y_pred_adjusted)

print(f"\n调整后的均方误差 (MSE): {mse_adjusted}")
print(f"调整后的均方根误差 (RMSE): {rmse_adjusted}")
print(f"调整后的平均绝对误差 (MAE): {mae_adjusted}")
print(f"调整后的 R² 得分: {r2_adjusted}")

# 统计预测正确的数量
correct_predictions = sum(1 for pred, actual in zip(y_pred_adjusted, y_test) if abs(pred - actual) <= 10)

# 计算预测正确率
accuracy = correct_predictions / len(y_test)

print(f"\n预测正确率: {accuracy:.5f}")

# 读取没有result列的数据集
new_data = pd.read_csv('New_Match_data.csv')  # 根据实际情况读取数据

# 对新数据集进行归一化
new_data[features] = scaler.transform(new_data[features])

# 使用训练好的模型进行预测
predicted_results = svr_model.predict(new_data[features])

# 将预测结果添加到新数据集中
new_data['result'] = predicted_results

# 按result从高到低排序
new_data_sorted = new_data.sort_values(by='result', ascending=False)

# 可视化输出
plt.figure(figsize=(12, 8))
sns.barplot(x='result', y='country', data=new_data_sorted)
plt.title('Predicted Result by Country')
plt.xlabel('Predicted Result')
plt.ylabel('Country')
plt.show()
